import 'dart:collection';

import 'package:device_calendar/device_calendar.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:photo_frame/mixin/auto_hide_loading.dart';
import 'package:photo_frame/net/http_manager.dart';
import 'package:photo_frame/net/model/event_dto.dart';
import 'package:photo_frame/provider/schedule_provider.dart';
import 'package:photo_frame/user/user_manager.dart';
import 'package:photo_frame/utils/a_logger.dart';
import 'package:photo_frame/utils/calendar_helper.dart';
import 'package:photo_frame/utils/localization_util.dart';
import 'package:photo_frame/widgets/app_bar_widget.dart';
import 'package:provider/provider.dart';

class ImportSchedulePagePage extends StatefulWidget {
  String? frameId;

  ImportSchedulePagePage(Map<String, dynamic>? args, {super.key}) {
    frameId = args?['frameId'];
  }

  @override
  State<StatefulWidget> createState() {
    return ImportSchedulePageState();
  }
}

class ImportSchedulePageState extends State<ImportSchedulePagePage>
    with AutoHideLoading {
  ImportSchedulePageViewModel _vm = ImportSchedulePageViewModel();

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _vm.init(context);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: commonAppBar(AppLocalizations.of(context)!.importScheduleTitle),
      body: ChangeNotifierProvider<ImportSchedulePageViewModel>(
        create: (BuildContext context) => _vm,
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 12.5),
          child: Column(
            children: [
              SizedBox(height: 10),
              Container(
                height: 27,
                width: double.infinity,
                alignment: Alignment.centerLeft,
                padding: EdgeInsets.only(left: 9),
                decoration: BoxDecoration(
                    color: Color(0xffFFDFDF),
                    borderRadius: BorderRadius.circular(5)),
                child: Text(
                  AppLocalizations.of(context)!.importScheduleTips,
                  style: TextStyle(color: Color(0xffFF4040), fontSize: 10),
                ),
              ),
              SizedBox(height: 11),
              Expanded(
                child: Consumer<ImportSchedulePageViewModel>(
                  builder: (BuildContext context, value, Widget? child) =>
                      ListView.separated(
                          physics: NeverScrollableScrollPhysics(),
                          itemBuilder: (context, index) => _calendarItemWidget(
                              context, index, value._list![index]),
                          separatorBuilder: (context, index) =>
                              SizedBox(height: 11),
                          itemCount: value._list?.length ?? 0),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _calendarItemWidget(BuildContext context, int index, Item item) {
    return Container(
      height: 66,
      child: Card(
        color: Colors.white,
        margin: EdgeInsets.zero,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)),
        child: Row(
          children: [
            SizedBox(width: 12.5),
            Image.asset(item.icon, width: 24, height: 24),
            SizedBox(width: 12),
            Expanded(
              child: Text(
                item.name,
                style: TextStyle(
                  color: Color(0xff555555),
                  fontSize: 14,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            CupertinoButton(
              padding: EdgeInsets.zero,
              onPressed: () {
                _vm._retrieveCalendarEvents(
                    context, widget.frameId ?? "", item.calendars);
              },
              child: Container(
                width: 52.5,
                height: 27,
                decoration: BoxDecoration(
                    color: Color(0xffEAECEE),
                    borderRadius: BorderRadius.circular(13.5)),
                margin: EdgeInsets.only(right: 17),
                child: Align(
                  child: Text(
                    textAlign: TextAlign.center,
                    AppLocalizations.of(context)!.importScheduleActionText,
                    style: TextStyle(color: Color(0xff555555), fontSize: 12),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

class ImportSchedulePageViewModel extends ChangeNotifier {
  final _gmailAccountName = "gmail";
  final _icloudAccountName = "icloud";
  final _outlookAccountName = "outlook";
  DeviceCalendarPlugin _deviceCalendarPlugin = DeviceCalendarPlugin();

  // List<Calendar>? _calendars;
  List<Item>? _list;

  init(BuildContext context) {
    _groupByAccount(context);
  }

  _groupByAccount(BuildContext context) async {
    var calendars =
        await CalendarHelper.instance.retrieveCalendars(force: true);
    if (calendars == null) {
      return;
    }
    Map<String, Item> calendarMap = {};
    for (var e in calendars) {
      if (e.isFotocube()) {
        //   /// todo test
        //   testCalendar.add(e);
        continue;
      }
      String key = "other";
      if (e.isGoogle()) {
        key = _gmailAccountName;
      } else if (e.isICloud()) {
        key = _icloudAccountName;
      } else if (e.isOutlook()) {
        key = _outlookAccountName;
      }
      var findCalendar = calendarMap[key];
      if (findCalendar != null) {
        findCalendar.calendars.add(e);
      } else {
        final calendar = buildItem(context, e);
        if (calendar != null) {
          calendarMap[key] = calendar;
        }
      }
    }
    print("calendarMap.values ${calendarMap.keys.length}");
    var list = calendarMap.values.toList();
    list.sort((a, b) {
      return a.priority.compareTo(b.priority);
    });
    _list = list;
    notifyListeners();
  }

  //
  /// iOS {calendarId: 1D7ED0F3-990D-435A-B3B4-61C51198CF63, eventId: B7AAF9D3-7C3C-4EF2-AEDE-F76637D751B3:21600D44-FB6E-43A9-A4BF-6B1F85EB62D5, eventTitle: 真的可以？google, eventDescription: null, eventStartDate: 1721962800000, eventStartTimeZone: Asia/Shanghai, eventEndDate: 1721966400000, eventEndTimeZone: Asia/Shanghai, eventAllDay: false, eventLocation: null, eventURL: null, availability: BUSY, eventStatus: NONE, attendees: [], organizer: null, reminders: []}
  Future _retrieveCalendarEvents(
      BuildContext context, String frameId, List<Calendar> calendars) async {
    await EasyLoading.show(
      maskType: EasyLoadingMaskType.black,
    );
    print("_retrieveCalendarEvents ${calendars.map((e) => e.accountName)}");
    //
    // for (var c in testCalendar) {
    //   // _deviceCalendarPlugin.deleteCalendar(c.id!);
    //   retrieveEventsFuture(c?.id).then((e) {
    //     ALogger.e(
    //         "testCalendar :${c?.id}  ${e.data?.map((e) => e.toJson()).toList()}");
    //   });
    // }
    var scheduleViewModel = context.read<ScheduleViewModel>();
    await Future.wait(calendars.map((calendar) {
      return retrieveCalendarEventsFuture(calendar.id, DateTime.now(),
              DateTime.now().add(const Duration(days: 30)))
          .then((res) {
        ALogger.d(
            "retrieveCalendarEventsFuture-add-org : ${res.data?.length}  ");
        return res.data
            ?.where((event) => filter(context, frameId, event))
            .map((e) => EventDTO.buildFromSystem(frameId, calendar, e))
            .toList();
      });
    })).then((e) async {
      ALogger.w("_retrieveCalendarEvents-add : ${e[0]?.length}  ");
      var filterEvents = e.expand((innerList) => innerList ?? []).toList();
      ALogger.w(
          "_retrieveCalendarEvents-add-filterEvents : ${filterEvents.length}  ");
      if (filterEvents.isEmpty) {
        return;
      }
      await scheduleViewModel.addMultiple(
          filterEvents.map((e) {
            var event = e as EventDTO;
            event.reminder = UserManager.instance.getId().toString();
            return event;
          }).toList(),
          isSystem: true);
      // await Future.wait(
      //     filterEvents.map((e) => scheduleViewModel.add(e, isSystem: true)));
    }).then((e) {
      Fluttertoast.showToast(
          msg: AppLocalizationsWrapper.instance
              .unwrap(context)
              .importSuccessful);
    }).catchError((e, stackTrace) {
      print(e);
      Fluttertoast.showToast(
          msg: e.msg ??
              AppLocalizationsWrapper.instance.unwrap(context).netError);
    }).whenComplete(() {
      EasyLoading.dismiss();
    });
  }

  buildItem(BuildContext context, Calendar calendar) {
    var lowerCase = calendar.accountName?.toLowerCase();
    if (lowerCase == null) {
      return;
    }
    int priority = 4;
    String icon = "images/icon_other_schedule.png";
    String name = AppLocalizationsWrapper.instance
        .unwrap(context)
        .importOtherScheduleName;
    if (lowerCase.contains(_gmailAccountName)) {
      priority = 1;
      icon = "images/icon_google_schedule.png";
      name = AppLocalizationsWrapper.instance
          .unwrap(context)
          .importGoogleScheduleName;
    } else if (lowerCase.contains(_icloudAccountName)) {
      priority = 2;
      icon = "images/icon_apple_schedule.png";
      name = AppLocalizationsWrapper.instance
          .unwrap(context)
          .importAppleScheduleName;
    } else if (lowerCase.contains(_outlookAccountName)) {
      priority = 3;
      icon = "images/icon_outlook_schedule.png";
      name = AppLocalizationsWrapper.instance
          .unwrap(context)
          .importOutlookScheduleName;
    }
    return Item(priority, icon, name, [calendar]);
  }

  filter(BuildContext context, String frameId, Event event) {
    final scheduleViewModel = context.read<ScheduleViewModel>();
    final frameEvents = scheduleViewModel.allEvent[frameId];
    return frameEvents == null ||
        frameEvents.indexWhere((e) =>
                e.event_id == event.eventId &&
                e.title == event.title &&
                e.dtstart == (event.start?.millisecondsSinceEpoch ?? 0)) ==
            -1;
  }

  Future<Result<UnmodifiableListView<Event>>> retrieveCalendarEventsFuture(
      String? calendarId, DateTime startDate, DateTime endDate) {
    return _deviceCalendarPlugin.retrieveEvents(
      calendarId,
      RetrieveEventsParams(startDate: startDate, endDate: endDate),
    );
  }
}

class Item {
  int priority;
  String icon;
  String name;
  List<Calendar> calendars;

  Item(this.priority, this.icon, this.name, this.calendars);
}
